package homelesspartners.client.widgets;

import homelesspartners.client.ServerFacade;
import homelesspartners.client.model.City;
import homelesspartners.client.model.Gift;
import homelesspartners.client.model.Shelter;
import homelesspartners.client.model.Story;
import homelesspartners.client.model.ThankYou;
import homelesspartners.client.model.User;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class VolunteerTabWidget extends Composite {

	protected VerticalPanel mainPanel = new VerticalPanel();
	protected CityPanel cityPanel = new CityPanel();
	protected ChangePasswordPanel changePasswordPanel = new ChangePasswordPanel();
	protected VolunteerPanel volunteerPanel = new VolunteerPanel();
	protected HTML currentCityLabel = new HTML("Your current city is: <b> None </b><br /><br />");
	protected InterviewForm interviewForm = new InterviewForm();
	protected EditInterviewPanel editInterviewPanel = new EditInterviewPanel();
	protected ShelterForm shelterForm = new ShelterForm();
	protected EditShelterPanel editShelterPanel = new EditShelterPanel();
	protected EditThankYouPanel editThankYouPanel = new EditThankYouPanel();
	protected ThankYouForm thankyouForm = new ThankYouForm();

	protected HTML greetText =
			new HTML(
					"This page provides information and tools for the volunteers that help run our program.  If you would like to volunteer, please see the 'questions' page on the 'Home' tab for information on how to get involved.<br/><br/>");
	protected MenuItem login = null;

	private MenuBar menuBar = new MenuBar();

	private static VolunteerTabWidget instance = new VolunteerTabWidget();

	public VolunteerTabWidget() {
		mainPanel.add(menuBar);

		login = new MenuItem("login", new Command() {

			public void execute() {
				if (User.getInstance().isLoggedIn()) {
					populateMenuBar();
				} else {
					LoginWidget.prompt();
				}
			}
		});

		menuBar.addItem(login);

		Image image = new Image("./images/fader.png");
		image.setWidth("728px");
		mainPanel.add(image);

		mainPanel.add(greetText);
		initWidget(mainPanel);
	}

	public void populateMenuBar() {
		// no permissions
		if (User.getInstance().isLoggedIn()) {
			menuBar.removeItem(login);
		}
		// typists and up
		if (User.getInstance().getRole() > 0) {
			populateBasicMenu();
			showCityPanel();
		}
		// coordinators and up
		if (User.getInstance().getRole() > 1) {
			populateCoordinatorMenu();
		}

		menuBar.addItem("change password", new Command() {

			public void execute() {
				showChangePasswordPanel();
			}
		});
	}

	private void populateBasicMenu() {
		mainPanel.add(currentCityLabel);

		menuBar.addItem(new MenuItem("change city", new Command() {

			public void execute() {
				showCityPanel();
			}

		}));
		MenuBar interviewsMenu = new MenuBar(true);
		MenuItem addInterview = new MenuItem("add new", new Command() {

			public void execute() {
				showAddNewInterview();
			}
		});
		MenuItem updateInterview = new MenuItem("update existing", new Command() {

			public void execute() {
				showUpdateInterview();
			}
		});
		interviewsMenu.addItem(addInterview);
		interviewsMenu.addItem(updateInterview);
		menuBar.addItem("interviews", interviewsMenu);

		MenuBar thankyousMenu = new MenuBar(true);
		MenuItem addThankYou = new MenuItem("add new", new Command() {

			public void execute() {
				showAddNewThankYou();
			}
		});
		MenuItem updateThankYou = new MenuItem("update existing", new Command() {

			public void execute() {
				showUpdateExistingThankYous();
			}
		});
		thankyousMenu.addItem(addThankYou);
		thankyousMenu.addItem(updateThankYou);
		menuBar.addItem("thank yous", thankyousMenu);

	}

	private void populateCoordinatorMenu() {
		menuBar.addItem(new MenuItem("volunteers", new Command() {

			public void execute() {
				showVolunteerPanel();
			}

		}));

		MenuBar sheltersMenu = new MenuBar(true);
		MenuItem addShelters = new MenuItem("add new", new Command() {

			public void execute() {
				showAddNewShelter();
			}
		});
		MenuItem updateShelters = new MenuItem("update existing", new Command() {

			public void execute() {
				showUpdateShelter();
			}
		});
		sheltersMenu.addItem(addShelters);
		sheltersMenu.addItem(updateShelters);
		menuBar.addItem("shelters", sheltersMenu);
	}

	public void showAddNewInterview() {
		if (isCurrentCityValid()) {
			clearMainPanel();
			interviewForm.setMode(InterviewForm.ADD_MODE);
			interviewForm.setStory(new Story());
			mainPanel.add(interviewForm);
		}
	}

	public void showAddNewThankYou() {
		clearMainPanel();
		thankyouForm.setMode(ThankYouForm.ADD_MODE);
		thankyouForm.setThankYou(new ThankYou());
		mainPanel.add(thankyouForm);

	}

	protected void showUpdateShelter() {
		if (isCurrentCityValid()) {
			editShelterPanel.reset();
			showUpdateExistingShelters();
		}
	}

	public void showAddNewShelter() {
		if (isCurrentCityValid()) {
			clearMainPanel();
			shelterForm.setMode(ShelterForm.ADD_MODE);
			shelterForm.setShelter(new Shelter());
			mainPanel.add(shelterForm);
		}
	}

	private void clearMainPanel() {
		mainPanel.remove(greetText);
		mainPanel.remove(cityPanel);
		mainPanel.remove(volunteerPanel);
		mainPanel.remove(interviewForm);
		mainPanel.remove(editInterviewPanel);
		mainPanel.remove(shelterForm);
		mainPanel.remove(editShelterPanel);
		mainPanel.remove(changePasswordPanel);
		mainPanel.remove(editThankYouPanel);
		mainPanel.remove(thankyouForm);
	}

	private boolean isCurrentCityValid() {
		if (User.getInstance().getCurrentCity() == null) {
			Window.alert("Please choose a city first.");
			return false;
		}
		return true;
	}

	public void showUpdateExistingInterviews() {
		if (isCurrentCityValid()) {
			clearMainPanel();
			interviewForm.setMode(InterviewForm.EDIT_MODE);
			mainPanel.add(editInterviewPanel);
		}
	}

	protected void showUpdateInterview() {
		if (isCurrentCityValid()) {
			editInterviewPanel.reset();
			showUpdateExistingInterviews();
		}
	}

	public void showUpdateExistingShelters() {
		if (isCurrentCityValid()) {
			clearMainPanel();
			shelterForm.setMode(ShelterForm.EDIT_MODE);
			mainPanel.add(editShelterPanel);
		}
	}

	public void showUpdateExistingThankYous() {
		clearMainPanel();
		thankyouForm.setMode(ThankYouForm.EDIT_MODE);
		mainPanel.add(editThankYouPanel);
	}

	public void showEditInterview() {
		clearMainPanel();
		mainPanel.add(interviewForm);
	}
	
	public void showEditThankYou() {
		clearMainPanel();
		mainPanel.add(thankyouForm);
	}

	public void showCityPanel() {
		clearMainPanel();
		mainPanel.add(cityPanel);
		cityPanel.refresh();
	}

	public void showChangePasswordPanel() {
		clearMainPanel();
		mainPanel.add(changePasswordPanel);
	}

	public void showVolunteerPanel() {
		clearMainPanel();
		mainPanel.add(volunteerPanel);
		volunteerPanel.refresh();
	}

	public void setCurrentCity(City city) {
		if (!city.isPopulated()) {
			ServerFacade.loadShelters(city);
		}
		User.getInstance().setCurrentCity(city);
		updateCurrentCityLabel();
		editInterviewPanel.reset();
	}

	void updateCurrentCityLabel() {
		City city = User.getInstance().getCurrentCity();
		if (city == null) {
			return;
		}
		String label = currentCityLabel.getText();
		label = label.substring(0, label.indexOf(':') + 1);
		label = label + " <b>" + city.getName() + "</b><br /><br />";
		currentCityLabel.setHTML(label);
	}

	public void noticeCityUpdated(City updatedCity) {
		if (updatedCity == User.getInstance().getCurrentCity()) {
			interviewForm.refreshShelters();
		}
	}

	private class CityPanel extends Composite {

		private VerticalPanel panel = new VerticalPanel();
		private HTML text = new HTML("<br />Please choose your city from the following list:<br />");
		private HTML space = new HTML("<br />");

		public CityPanel() {
			initWidget(panel);
		}

		public void refresh() {
			panel.clear();
			panel.add(text);
			for (Iterator cityIter = City.getCities().iterator(); cityIter.hasNext();) {
				final City city = (City) cityIter.next();
				Hyperlink cityName = new Hyperlink(city.getName(), "");
				cityName.addClickListener(new ClickListener() {

					public void onClick(Widget sender) {
						setCurrentCity(city);
					}
				});
				panel.add(cityName);
			}
			updateCurrentCityLabel();
			panel.add(space);
		}
	}

	private class ChangePasswordPanel extends Composite implements ClickListener {

		private VerticalPanel panel = new VerticalPanel();
		private HTML text = new HTML("<br />Please enter a new password and click 'Update' below.<br /><br />");
		private PasswordTextBox password = new PasswordTextBox();
		private PushButton update = new PushButton("Update", this);

		public ChangePasswordPanel() {
			panel.add(text);
			FlexTable table = new FlexTable();
			panel.add(table);
			table.setWidget(0, 0, new HTML("<b>Password</b>"));
			table.setWidget(0, 1, password);
			table.setWidget(1, 1, update);
			table.setWidget(2, 0, new HTML("<br />"));
			initWidget(panel);
		}

		public void onClick(Widget sender) {
			if (sender == update) {
				String pwd = password.getText();
				if (pwd.length() < 4) {
					Window.alert("The password must be at least 4 characters long");
					return;
				}
				ServerFacade.updatePassword(password.getText());
			}
		}
	}

	private class VolunteerPanel extends Composite implements ClickListener, ChangeListener {

		private FlexTable table = new FlexTable();
		private TextBox email = new TextBox();
		private PasswordTextBox password = new PasswordTextBox();
		private ListBox permissions = new ListBox();
		private String none = "no access to the volunteer tab";
		private String typist = "can add, edit, and delete stories";
		private String coordinator = "can also manage shelters, and grant typist access";
		private String facilitator = "can also grant coordinator access";
		private HTML permissionText = new HTML(none);

		private HTML instructions =
				new HTML(
						"<br />This page allows you to manage your volunteers and what access they have to the website.  You can either modify the access for existing accounts, or create a new account if one has not been created yet.<br /><br /><br /><b>Existing Accounts</b><br />If the volunteer already has an account, enter the email address and select the desired permission level, then click 'Update'.<br/><br/>");

		private HTML instructions2 =
				new HTML(
						"<br /><br /><br /><b>New Accounts</b><br />If an account has not been created for this volunteer yet, you can create a new one by entering an email address, permission level, and password, then click 'Create'.<br/><br/>");

		private PushButton update = new PushButton("Update", this);
		private PushButton create = new PushButton("Create", this);

		private User volunteer = new User();

		public VolunteerPanel() {
			permissions.addChangeListener(this);
			table.setWidget(0, 0, instructions);
			table.getFlexCellFormatter().setColSpan(0, 0, 3);
			table.setWidget(1, 0, new HTML("<b>Email Address</b>"));
			table.setWidget(1, 1, email);
			table.setWidget(2, 0, new HTML("<b>Permission Level&nbsp;</b>"));
			table.setWidget(2, 1, permissions);
			table.setWidget(2, 2, permissionText);
			table.setWidget(3, 1, update);

			table.setWidget(4, 0, instructions2);
			table.getFlexCellFormatter().setColSpan(4, 0, 3);
			table.setWidget(5, 0, new HTML("<b>Password</b>"));
			table.setWidget(5, 1, password);
			table.setWidget(5, 2, new HTML("(required for new accounts only)"));
			table.setWidget(6, 1, create);

			table.setWidget(7, 0, new Label(" "));
			initWidget(table);
		}

		public void refresh() {
			permissions.clear();

			User user = User.getInstance();
			if (user.getRole() > User.TYPIST) {
				permissions.addItem("None", "0");
				permissions.addItem("Typist", "1");
			}
			if (user.getRole() > User.COORDINATOR) {
				permissions.addItem("Coordinator", "2");
			}
			if (user.getRole() > User.FACILITATOR) {
				permissions.addItem("Facilitator", "3");
			}

		}

		public void onClick(Widget sender) {
			updateVolunteer();
			if (sender == update) {
				if (volunteer.getPassword() != null & volunteer.getPassword().length() > 0) {
					Window
							.alert("You can not specify a password for an existing account.  Please clear the password and click 'Update' again, or click 'Create' below if you are trying to create a new account.");
					return;
				}
				ServerFacade.updateVolunteer(volunteer);
			} else if (sender == create) {
				ServerFacade.createNewVolunteer(volunteer);
			}
		}

		private void updateVolunteer() {
			volunteer.setEmailAddress(email.getText());
			volunteer.setPassword(password.getText());
			String value = permissions.getValue(permissions.getSelectedIndex());
			int role = Integer.parseInt(value);
			volunteer.setRole(role);
		}

		public void onChange(Widget sender) {
			int selected = permissions.getSelectedIndex();
			if (selected == 0) {
				permissionText.setHTML(none);
			} else if (selected == 1) {
				permissionText.setHTML(typist);
			} else if (selected == 2) {
				permissionText.setHTML(coordinator);
			} else if (selected == 3) {
				permissionText.setHTML(facilitator);
			}

		}

		protected void clear() {
			volunteer = new User();
			email.setText(volunteer.getEmailAddress());
			password.setText(volunteer.getPassword());
		}
	}

	private class InterviewForm extends Composite implements ClickListener {

		private final static int ADD_MODE = 0;
		private final static int EDIT_MODE = 1;

		private FlexTable table = new FlexTable();
		private int mode = ADD_MODE;

		private ListBox shelters = new ListBox();
		private TextBox name = new TextBox();
		private TextBox initial = new TextBox();
		private RadioButton male = new RadioButton("gender", "Male");
		private RadioButton female = new RadioButton("gender", "Female");
		private TextBox id = new TextBox();
		private TextArea details = new TextArea();
		private VerticalPanel giftPanel = new VerticalPanel();
		private TextBox[] gifts = new TextBox[Story.MAX_GIFTS];
		private HTML[] giftDonors = new HTML[Story.MAX_GIFTS];

		private PushButton add = new PushButton("Add to Site", this);
		private PushButton clear = new PushButton("Clear All", this);
		private PushButton save = new PushButton("Save", this);
		private PushButton delete = new PushButton("Delete", this);
		private PushButton cancel = new PushButton("Go Back", this);

		private HorizontalPanel buttonPanel = new HorizontalPanel();

		private HTML instructions = new HTML("");
		private String addInstructions =
				"<br />To add an interview to the site, complete the form below and click 'Add'.<br /><br />";
		private String editInstructions =
				"<br />To edit the interview, update the fields below and click 'Save'.  You can also remove the story by clicking 'Delete'.<br /><br />";

		private HTML idFormat = new HTML("");

		Story story = new Story();

		public InterviewForm() {

			initial.setWidth("30");
			initial.setMaxLength(1);
			details.setWidth("400");
			details.setHeight("80");
			name.setMaxLength(32);
			id.setMaxLength(32);

			table.setWidget(0, 0, instructions);
			table.getFlexCellFormatter().setColSpan(0, 0, 2);
			table.setWidget(1, 0, new HTML("<b>Shelter</b>"));
			table.setWidget(1, 1, shelters);
			table.setWidget(2, 0, new HTML("<b>First Name</b>"));
			table.setWidget(2, 1, name);
			table.setWidget(3, 0, new HTML("<b>Last Initial</b>"));
			table.setWidget(3, 1, initial);
			table.setWidget(4, 0, new HTML("<b>Gender</b>"));
			table.setWidget(4, 1, male);
			table.setWidget(5, 1, female);
			table.setWidget(6, 0, new HTML("<b>Assigned ID</b>"));
			HorizontalPanel idFormatPanel = new HorizontalPanel();
			idFormatPanel.add(id);
			idFormatPanel.add(new Label(" "));
			idFormatPanel.add(idFormat);
			table.setWidget(6, 1, idFormatPanel);
			table.setWidget(7, 0, new HTML("<b>Story Details</b>"));
			table.setWidget(7, 1, details);
			table.setWidget(8, 0, giftPanel);
			table.getFlexCellFormatter().setColSpan(8, 0, 2);
			table.setWidget(9, 0, new Label(" "));
			table.setWidget(10, 0, buttonPanel);
			table.getFlexCellFormatter().setColSpan(10, 0, 2);
			table.setWidget(11, 0, new Label(" "));

			shelters.addChangeListener(new ChangeListener() {

				public void onChange(Widget sender) {
					int selected = shelters.getSelectedIndex();
					if (selected == 0) {
						idFormat.setHTML("");
						return;
					}
					Shelter shelter = (Shelter) User.getInstance().getCurrentCity().getShelters().get(selected - 1);
					idFormat.setHTML(shelter.getIdFormat());
				}
			});

			giftPanel.clear();
			giftPanel
					.add(new HTML(
							"<br/><b>Gift Requests</b><br />For each gift request, enter the description below (up to 4 gifts).  "
									+ "If you are editing an existing story and need to delete a gift, just make the description blank and click 'Save'.  "
									+ "If you are changing a gift that has already been pledged, please <b>contact the donor</b> to advise them of the change.<br /><br />"));
			giftPanel.add(new HTML(
					"(eg. \"warm footwear, size 10 male\" or \"pants, size 36 waist x 32 leg, color blue\")"));
			FlexTable giftTable = new FlexTable();
			giftPanel.add(giftTable);
			for (int x = 0; x < gifts.length; x++) {
				gifts[x] = new TextBox();
				gifts[x].setWidth("400");
				gifts[x].setMaxLength(64);
				giftTable.setWidget(x, 0, gifts[x]);
				giftDonors[x] = new HTML("");
				giftTable.setWidget(x, 1, giftDonors[x]);
			}

			add.setWidth("100px");
			clear.setWidth("100px");

			buttonPanel.add(add);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(clear);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(save);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(delete);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(cancel);

			table.setWidth("728px");

			initWidget(table);
		}

		private void refreshButtons() {
			add.setVisible(false);
			clear.setVisible(false);
			save.setVisible(false);
			delete.setVisible(false);
			cancel.setVisible(false);

			if (mode == ADD_MODE) {
				add.setVisible(true);
				clear.setVisible(true);
				shelters.setEnabled(true);
			} else if (mode == EDIT_MODE) {
				save.setVisible(true);
				delete.setVisible(true);
				cancel.setVisible(true);
				shelters.setEnabled(false);
			}

			delete.setEnabled(true);
			save.setEnabled(true);

		}

		public void setStory(Story aStory) {
			refreshShelters();
			story = aStory;
			refresh();
		}

		public void refresh() {

			name.setFocus(true);
			name.setText(story.getFirstName());
			initial.setText(story.getLastInitial());
			if (story.getGender() == Story.MALE) {
				male.setChecked(true);
				female.setChecked(false);
			} else {
				male.setChecked(false);
				female.setChecked(true);
			}
			id.setText(story.getAssignedId());
			details.setText(story.getStory());

			refreshGiftFields();
			refreshButtons();
		}

		private void refreshGiftFields() {
			for (int x = 0; x < gifts.length; x++) {
				giftDonors[x].setHTML("");
				Gift gift = story.getGifts()[x];
				if (gift != null) {
					gifts[x].setText(gift.getDescription());
					if (gift.getDonor() != null && gift.getDonor().length() > 0) {
						giftDonors[x].setHTML("(donor " + gift.getDonor() + ")");
					}
				} else {
					gifts[x].setText("");
				}
			}
		}

		public void refreshShelters() {

			shelters.clear();
			shelters.addItem("", "");

			if (User.getInstance().getCurrentCity() != null && User.getInstance().getCurrentCity().isPopulated()) {
				ArrayList sheltersList = User.getInstance().getCurrentCity().getShelters();
				int x = 0;
				for (Iterator iter = sheltersList.iterator(); iter.hasNext(); x++) {
					Shelter shelter = (Shelter) iter.next();
					shelters.addItem(shelter.getName(), new Integer(shelter.getId()).toString());
					if (story.getShelter() != null && story.getShelter().getName().equals(shelter.getName())) {
						shelters.setSelectedIndex(x + 1);
					}
				}
			}
		}

		public void setMode(int mode) {
			this.mode = mode;
			if (mode == ADD_MODE) {
				instructions.setHTML(addInstructions);
			} else {
				instructions.setHTML(editInstructions);
			}
			refreshButtons();
		}

		public void onClick(Widget sender) {
			if (sender == add) {
				updateStory();
				String error = story.validate();
				if (error == null) {
					ServerFacade.addInterviewCheckFirst(story);
				} else {
					Window.alert(error);
				}
			} else if (sender == clear) {
				setStory(new Story());
			} else if (sender == cancel) {
				showUpdateExistingInterviews();
			} else if (sender == save) {
				updateStory();
				String error = story.validate();
				if (error == null) {
					ServerFacade.updateInterview(story);
				} else {
					Window.alert(error);
				}
			} else if (sender == delete) {
				if (!Window.confirm("Are you sure you want to delete this?")) {
					return;
				}
				ServerFacade.deleteInterview(story.getId());
			}
		}

		private void updateStory() {
			story.setFirstName(name.getText());
			story.setLastInitial(initial.getText());
			story.setAssignedId(id.getText());
			story.setStory(details.getText());

			if (male.isChecked()) {
				story.setGender(Story.MALE);
			} else {
				story.setGender(Story.FEMALE);
			}

			for (int x = 0; x < gifts.length; x++) {
				Gift gift = story.getGifts()[x];
				if (gift == null) {
					if (gifts[x].getText() != null && gifts[x].getText().length() != 0) {
						gift = new Gift();
						gift.setId(0 - x - 1);
						gift.setDescription(gifts[x].getText());
						story.addGift(gift);
					}
				} else {
					gift.setDescription(gifts[x].getText());
				}
			}

			int selected = shelters.getSelectedIndex() - 1;
			if (selected >= 0) {
				Shelter shelter = (Shelter) User.getInstance().getCurrentCity().getShelters().get(selected);
				story.setShelter(shelter);
			}

			refreshShelters();
			refreshGiftFields();
			refreshButtons();

		}

	}

	private class ThankYouForm extends Composite implements ClickListener {

		private final static int ADD_MODE = 0;
		private final static int EDIT_MODE = 1;

		private FlexTable table = new FlexTable();
		private int mode = ADD_MODE;

		private TextBox header = new TextBox();
		private TextArea note = new TextArea();

		private PushButton add = new PushButton("Add to Site", this);
		private PushButton clear = new PushButton("Clear All", this);
		private PushButton save = new PushButton("Save", this);
		private PushButton delete = new PushButton("Delete", this);
		private PushButton cancel = new PushButton("Go Back", this);

		private HorizontalPanel buttonPanel = new HorizontalPanel();

		private HTML instructions = new HTML("");
		private String addInstructions =
				"<br />To add a thank you note to the site, complete the form below and click 'Add'.<br /><br />";
		private String editInstructions =
				"<br />To edit the thank you note, update the fields below and click 'Save'.  You can also remove the note by clicking 'Delete'.<br /><br />";

		ThankYou thankyou = new ThankYou();

		public ThankYouForm() {

			header.setMaxLength(256);
			header.setWidth("400");
			note.setWidth("400");
			note.setHeight("80");

			table.setWidget(0, 0, instructions);
			table.getFlexCellFormatter().setColSpan(0, 0, 2);
			table.setWidget(1, 0, new HTML("<b>Header</b>"));
			table.setWidget(1, 1, header);
			table.setWidget(2, 0, new HTML("<b>Note</b>"));
			table.setWidget(2, 1, note);
			table.setWidget(3, 0, buttonPanel);
			table.getFlexCellFormatter().setColSpan(3, 0, 2);
			table.setWidget(11, 0, new HTML("<br /><br /> "));

			add.setWidth("100px");
			clear.setWidth("100px");

			buttonPanel.add(add);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(clear);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(save);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(delete);
			buttonPanel.add(new HTML("&nbsp;"));
			buttonPanel.add(cancel);

			table.setWidth("728px");

			initWidget(table);
		}

		private void refreshButtons() {
			add.setVisible(false);
			clear.setVisible(false);
			save.setVisible(false);
			delete.setVisible(false);
			cancel.setVisible(false);

			if (mode == ADD_MODE) {
				add.setVisible(true);
				clear.setVisible(true);
			} else if (mode == EDIT_MODE) {
				save.setVisible(true);
				delete.setVisible(true);
				cancel.setVisible(true);
			}

			delete.setEnabled(true);
			save.setEnabled(true);

		}

		public void setThankYou(ThankYou aThankYou) {
			thankyou = aThankYou;
			refresh();
		}

		public void refresh() {

			header.setFocus(true);
			header.setText(thankyou.getTitle());
			note.setText(thankyou.getThankyou());

			refreshButtons();
		}

		public void setMode(int mode) {
			this.mode = mode;
			if (mode == ADD_MODE) {
				instructions.setHTML(addInstructions);
			} else {
				instructions.setHTML(editInstructions);
			}
			refreshButtons();
		}

		public void onClick(Widget sender) {
			if (sender == add) {
				updateThankYou();
				String error = thankyou.validate();
				if (error == null) {
					ServerFacade.addThankYou(thankyou);
				} else {
					Window.alert(error);
				}
			} else if (sender == clear) {
				setThankYou(new ThankYou());
			} else if (sender == cancel) {
				showUpdateExistingThankYous();
			} else if (sender == save) {
				updateThankYou();
				String error = thankyou.validate();
				if (error == null) {
					ServerFacade.updateThankYou(thankyou);
				} else {
					Window.alert(error);
				}
			} else if (sender == delete) {
				if (!Window.confirm("Are you sure you want to delete this?")) {
					return;
				}
				ServerFacade.deleteThankYou(thankyou.getId());
			}
		}

		private void updateThankYou() {
			thankyou.setTitle(header.getText());
			thankyou.setThankyou(note.getText());
			refreshButtons();
		}

	}

	private class EditInterviewPanel extends Composite implements ClickListener {

		private FlexTable table = new FlexTable();
		private FlexTable headerTable = new FlexTable();
		private VerticalPanel panel = new VerticalPanel();
		protected ListBox shelters = new ListBox();
		protected TextBox assignedId = new TextBox();
		protected TextBox name = new TextBox();

		private HTML instructions =
				new HTML(
						"To edit an interview, select the shelter it is in and enter the name or id, then click 'Search'.  A list of matching stories will be displayed below.<br /><br />");
		private HTML instructionsDeux =
				new HTML(
						"<br /><br />Click on the interview you want to edit, and follow the instructions on the next page.<br /><br />");
		private PushButton search = new PushButton("Search", this);

		public EditInterviewPanel() {

			panel.add(instructions);
			panel.add(headerTable);
			panel.add(new Label(" "));
			panel.add(instructionsDeux);
			panel.add(table);
			panel.add(new Label(" "));

			table.setCellPadding(2);
			table.setCellSpacing(2);

			headerTable.setWidget(0, 0, new HTML("<b>Shelter&nbsp;&nbsp;</b>"));
			headerTable.setWidget(0, 1, shelters);
			headerTable.setWidget(1, 0, new HTML("<b>First Name&nbsp;&nbsp;</b>"));
			headerTable.setWidget(1, 1, name);
			headerTable.setWidget(2, 0, new HTML("<b>Assigned Id&nbsp;&nbsp;</b>"));
			headerTable.setWidget(2, 1, assignedId);
			headerTable.setWidget(3, 1, search);

			initWidget(panel);
		}

		public void reset() {
			resetTable();
			shelters.clear();
			shelters.addItem("", "");
			shelters.setSelectedIndex(0);
			if (User.getInstance().getCurrentCity().getShelters() == null) {
				return; // not populated yet
			}
			for (Iterator shelterIter = User.getInstance().getCurrentCity().getShelters().iterator(); shelterIter
					.hasNext();) {
				final Shelter shelter = (Shelter) shelterIter.next();
				shelters.addItem(shelter.getName(), "" + shelter.getId());
			}
		}

		private void resetTable() {
			table.clear();
			table.setWidget(0, 0, new HTML("<b>Assigned ID</b>"));
			table.setWidget(0, 1, new HTML("&nbsp;&nbsp;"));
			table.setWidget(0, 2, new HTML("<b>Name</b>"));

		}

		public void refresh(ArrayList stories) {
			resetTable();
			int row = 1;
			if (stories != null) {
				for (Iterator storyIterator = stories.iterator(); storyIterator.hasNext(); row++) {
					addStoryToList(row, storyIterator);
				}
			}
		}

		private void addStoryToList(int row, Iterator storyIterator) {
			final Story story = (Story) storyIterator.next();
			Hyperlink text = new Hyperlink(story.getFirstName() + " " + story.getLastInitial(), true, "");
			text.addClickListener(new ClickListener() {

				public void onClick(Widget sender) {
					interviewForm.setStory(story);
					showEditInterview();
				}
			});
			table.setWidget(row, 0, new HTML(story.getAssignedId()));
			table.setWidget(row, 2, text);

		}

		public void onClick(Widget sender) {
			if (sender == search) {
				int selected = shelters.getSelectedIndex();
				if (selected < 1) {
					Window.alert("Please select a shelter first.");
					return;
				}
				int shelterId = (new Integer(shelters.getValue(selected))).intValue();
				String idQuery = assignedId.getText();
				String nameQuery = name.getText();
				ServerFacade.loadStories(shelterId, idQuery, nameQuery);
			}
		}

	}

	private class EditThankYouPanel extends Composite implements ClickListener {

		private FlexTable headerTable = new FlexTable();
		private VerticalPanel panel = new VerticalPanel();
		private VerticalPanel list = new VerticalPanel();
		protected TextBox header = new TextBox();

		private HTML instructions =
				new HTML(
						"To edit a thank you note, enter a portion of the header, then click 'Search'.  A list of matching thank you notes will be displayed below.<br /><br />");
		private HTML instructionsDeux =
				new HTML(
						"<br />Click on the thank you note you want to edit, and follow the instructions on the next page.<br /><br />");
		private PushButton search = new PushButton("Search", this);

		public EditThankYouPanel() {

			panel.add(instructions);
			panel.add(headerTable);
			panel.add(new HTML("<br />"));
			panel.add(instructionsDeux);
			panel.add(list);
			panel.add(new HTML("<br />"));

			headerTable.setWidget(0, 0, new HTML("<b>Header&nbsp;&nbsp;</b>"));
			headerTable.setWidget(0, 1, header);
			headerTable.setWidget(1, 1, search);

			initWidget(panel);
		}

		public void reset() {
			list.clear();
		}

		public void refresh(ArrayList thankyous) {
			reset();
			if (thankyous != null) {
				for (Iterator thankyousIterator = thankyous.iterator(); thankyousIterator.hasNext();) {
					final ThankYou thanks = (ThankYou) thankyousIterator.next();
					Hyperlink text = new Hyperlink(thanks.getTitle(), true, "");
					text.addClickListener(new ClickListener() {

						public void onClick(Widget sender) {
							thankyouForm.setThankYou(thanks);
							showEditThankYou();
						}
					});
					list.add(text);
				}
			}
		}

		public void onClick(Widget sender) {
			if (sender == search) {
				String headerQuery = header.getText();
				if (headerQuery.length() < 1) {
					Window.alert("Please enter a portion of the header first.");
					return;
				}
				ServerFacade.getThankYous(headerQuery);
			}
		}

	}

	private class ShelterForm extends Composite implements ClickListener {

		private final static int ADD_MODE = 0;
		private final static int EDIT_MODE = 1;

		private VerticalPanel panel = new VerticalPanel();
		private FlexTable table = new FlexTable();
		private int mode = ADD_MODE;

		private TextBox name = new TextBox();
		private TextBox address = new TextBox();
		private TextBox phone = new TextBox();
		private TextBox website = new TextBox();
		private TextBox idFormat = new TextBox();
		private TextBox whatDoTheyDo = new TextBox();
		private TextBox whatDoTheyNeed = new TextBox();
		private TextArea details = new TextArea();

		private HorizontalPanel buttons = new HorizontalPanel();
		private PushButton add = new PushButton("Add", this);
		private PushButton clear = new PushButton("Clear", this);
		private PushButton save = new PushButton("Save", this);
		private PushButton delete = new PushButton("Delete", this);
		private PushButton cancel = new PushButton("Go Back", this);

		private HTML instructions = new HTML("");
		private String addInstructions =
				"<br />To add a new shelter for this city, complete the form below and click 'Add'.<br /><br />";
		private String editInstructions =
				"<br />To edit the shelter, update the fields below and click 'Save'.  You can also remove the shelter by clicking 'Delete'.  Note that if the shelter has stories added to it, they must all be removed before the shelter can be deleted.<br /><br />";

		private PopupPanel info = new PopupPanel(true);
		private HTML idFormatText =
				new HTML(
						"This is the format of the id used by the shelter to identify a client in order to distribute the gifts.<br /><br />"
								+ "If you do not know the format the shelter would like to use, please ask them.  Common examples are<br />"
								+ "date of birth (eg. YYYYMMDD), Room # where the client is staying, etc.<br /><br />"
								+ "<b>IMPORTANT:</b> You need to be as specific as possible when entering the format.  This format will be displayed<br />"
								+ "to the typists when they are adding stories, and if each typist enters the ID value differently, it may be<br />"
								+ "very difficult for the shelters to correctly sort and distribute the gifts.  For example:<br /><br />"
								+ "Instead of 'Birthdate'<br />" + "Specify 'Birthdate (MMDDYY)'<br/><br />"
								+ "or<br /><br />" + "Instead of 'Room and Bed Number'<br />"
								+ "Specify 'Room and Bed Number (RM-BD)'");
		private HTML whatDoText =
				new HTML(
						"This should briefly state what this shelter does.  Examples might be:<br /><br />"
								+ "- Provide emergency housing for 1000 homeless each night<br />"
								+ "- Provide supplies and short-term housing for 500 people as well as substance abuse treatment.<br /><br />"
								+ "This information will be displayed on the 'choose shelter' page to help donors learn about what each shelter does.");
		private HTML whatNeedText =
				new HTML(
						"This can be used to give examples of the types of donations the shelter needs on an ongoing basis<br />"
								+ "(eg. jackets, toiletries, baby care items).  Please ask the shelter if they would like to include <br />"
								+ "some of their ongoing needs.<br /><br />"
								+ "This information will be displayed on the 'choose shelter' page.");
		private HTML detailsText =
				new HTML(
						"This can be used to provide additional information that donors may need to know before sending gifts to the shelter.<br />"
								+ "Examples might include:<br /><br />"
								+ "- Instructions of where and how to deliver the gifts<br />"
								+ "- Hours of operations<br />"
								+ "- Items they can not accept (cash, certain food products, etc)<br />"
								+ "- Specific gift wrapping requirements<br /><br />"
								+ "This information will be displayed on the 'final' page with a list of the pledges for each donor.");

		Shelter shelter = new Shelter();

		public ShelterForm() {

			info.setStylePrimaryName("popup");

			panel.add(instructions);
			panel.add(table);
			panel.add(new Label(" "));

			name.setMaxLength(32);
			address.setMaxLength(64);
			phone.setMaxLength(16);
			website.setMaxLength(128);
			idFormat.setMaxLength(128);
			whatDoTheyDo.setMaxLength(256);
			whatDoTheyNeed.setMaxLength(256);

			address.setWidth("400");
			idFormat.setWidth("400");
			website.setWidth("400");
			whatDoTheyDo.setWidth("400");
			whatDoTheyNeed.setWidth("400");
			details.setWidth("400");
			details.setHeight("80");
			name.setMaxLength(32);

			Image unusedImg = new Image("./images/info-icon.gif"); // for some
			// reason it GWT
			// needs this or
			// it mis-sizes
			// the image
			panel.add(unusedImg);
			unusedImg.setVisible(false);

			PushButton idFormatImg = new PushButton(new Image("./images/info-icon.gif"));
			idFormatImg.setWidth("15px");
			idFormatImg.addClickListener(new ClickListener() {

				public void onClick(Widget sender) {
					info.clear();
					info.setWidget(idFormatText);
					info.center();
					info.show();
				}
			});
			PushButton whatDoImg = new PushButton(new Image("./images/info-icon.gif"));
			whatDoImg.setWidth("15px");
			whatDoImg.addClickListener(new ClickListener() {

				public void onClick(Widget sender) {
					info.clear();
					info.setWidget(whatDoText);
					info.center();
					info.show();
				}
			});

			PushButton whatNeedImg = new PushButton(new Image("./images/info-icon.gif"));
			whatNeedImg.setWidth("15px");
			whatNeedImg.addClickListener(new ClickListener() {

				public void onClick(Widget sender) {
					info.clear();
					info.setWidget(whatNeedText);
					info.center();
					info.show();
				}
			});

			PushButton detailsImg = new PushButton(new Image("./images/info-icon.gif"));
			detailsImg.setWidth("15px");
			detailsImg.addClickListener(new ClickListener() {

				public void onClick(Widget sender) {
					info.clear();
					info.setWidget(detailsText);
					info.center();
					info.show();
				}
			});

			table.setWidget(0, 0, new HTML("<b>Shelter Name"));
			table.setWidget(0, 1, name);
			table.getFlexCellFormatter().setWidth(0, 1, "405");
			table.setWidget(1, 0, new HTML("<b>Address"));
			table.setWidget(1, 1, address);
			table.setWidget(2, 0, new HTML("<b>Phone #"));
			table.setWidget(2, 1, phone);
			table
					.setWidget(
							3,
							0,
							new HTML(
									"<b>Website&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</b>http://"));
			table.setWidget(3, 1, website);
			table.setWidget(4, 0, new HTML("<b>Assigned ID Format"));
			table.setWidget(4, 1, idFormat);
			table.setWidget(4, 2, idFormatImg);
			table.getFlexCellFormatter().setWidth(4, 2, "150");
			table.setWidget(5, 0, new HTML("<b>What do they do?"));
			table.setWidget(5, 1, whatDoTheyDo);
			table.setWidget(5, 2, whatDoImg);
			table.setWidget(6, 0, new HTML("<b>What do they need?"));
			table.setWidget(6, 1, whatDoTheyNeed);
			table.setWidget(6, 2, whatNeedImg);
			table.setWidget(7, 0, new HTML("<b>Gift Delivery & <br />Additional Details"));
			table.setWidget(7, 1, details);
			table.setWidget(7, 2, detailsImg);
			table.setWidget(8, 0, new Label(" "));
			table.setWidget(9, 1, buttons);

			buttons.add(add);
			buttons.add(new Label(" "));
			buttons.add(clear);
			buttons.add(new Label(" "));
			buttons.add(save);
			buttons.add(new Label(" "));
			buttons.add(delete);
			buttons.add(new Label(" "));
			buttons.add(cancel);

			table.setWidth("728px");

			initWidget(panel);
		}

		private void refreshButtons() {

			add.setVisible(false);
			clear.setVisible(false);
			save.setVisible(false);
			delete.setVisible(false);
			cancel.setVisible(false);

			if (mode == ADD_MODE) {
				add.setVisible(true);
				clear.setVisible(true);
			} else if (mode == EDIT_MODE) {
				save.setVisible(true);
				delete.setVisible(true);
				cancel.setVisible(true);
			}

		}

		public void setShelter(Shelter aShelter) {
			shelter = aShelter;
			shelter.setCityId(User.getInstance().getCurrentCity().getId());
			refresh();
		}

		public void refresh() {

			name.setFocus(true);
			name.setText(shelter.getName());
			address.setText(shelter.getAddress());
			website.setText(shelter.getWebsite());
			phone.setText(shelter.getPhone());
			idFormat.setText(shelter.getIdFormat());
			whatDoTheyDo.setText(shelter.getWhatTheyDo());
			whatDoTheyNeed.setText(shelter.getWhatTheyNeed());
			details.setText(shelter.getAdditionalDetails());

			refreshButtons();
		}

		public void setMode(int mode) {
			this.mode = mode;
			if (mode == ADD_MODE) {
				instructions.setHTML(addInstructions);
			} else {
				instructions.setHTML(editInstructions);
			}
			refreshButtons();
		}

		public void onClick(Widget sender) {
			if (sender == add) {
				updateShelter();
				String error = shelter.validate();
				if (error == null) {
					ServerFacade.addShelter(shelter);
				} else {
					Window.alert(error);
				}
			} else if (sender == clear) {
				setShelter(new Shelter());
			} else if (sender == cancel) {
				showUpdateExistingShelters();
			} else if (sender == save) {
				updateShelter();
				String error = shelter.validate();
				if (error == null) {
					ServerFacade.updateShelter(shelter);
				} else {
					Window.alert(error);
				}
			} else if (sender == delete) {
				if (!Window.confirm("Are you sure you want to delete this?")) {
					return;
				}
				ServerFacade.deleteShelter(shelter.getId());
			}
		}

		private void updateShelter() {
			shelter.setName(name.getText());
			shelter.setAddress(address.getText());
			shelter.setPhone(phone.getText());
			shelter.setWebsite(website.getText());
			shelter.setIdFormat(idFormat.getText());
			shelter.setWhatTheyDo(whatDoTheyDo.getText());
			shelter.setWhatTheyNeed(whatDoTheyNeed.getText());
			shelter.setAdditionalDetails(details.getText());

			refreshButtons();

		}

	}

	private class EditShelterPanel extends Composite {

		private VerticalPanel panel = new VerticalPanel();
		private HTML chooseShelterText =
				new HTML(
						"<br />To edit a shelter, please click on the name below and follow the instructions on the next page.<br/><br/>");
		private HTML noShelterText = new HTML("<br />No shelters available for this city.<br/><br/>");

		public EditShelterPanel() {
			initWidget(panel);
		}

		public void reset() {
			panel.clear();

			if (User.getInstance().getCurrentCity().getShelters() == null) {
				panel.add(noShelterText);
				return; // not populated yet
			}
			panel.add(chooseShelterText);

			for (Iterator shelterIter = User.getInstance().getCurrentCity().getShelters().iterator(); shelterIter
					.hasNext();) {
				final Shelter shelter = (Shelter) shelterIter.next();
				Hyperlink shelterLink = new Hyperlink(shelter.getName(), "");
				shelterLink.addClickListener(new ClickListener() {

					public void onClick(Widget sender) {
						shelterForm.setShelter(shelter);
						showEditShelter();
					}
				});

				panel.add(shelterLink);
			}
			panel.add(new Label(" "));
		}

	}

	public void showEditShelter() {
		clearMainPanel();
		mainPanel.add(shelterForm);
	}

	public void noticeLogin() {
		populateMenuBar();
	}

	public static VolunteerTabWidget getInstance() {
		return instance;
	}

	public void completedDeleteInterview(Object result) {
		boolean isDeleted = ((Boolean) result).booleanValue();

		if (isDeleted) {
			Window.alert("The story has been deleted.");
			interviewForm.story.getShelter().deleteStory(interviewForm.story);
			interviewForm.setStory(new Story());
			showUpdateInterview();
		} else {
			failedDeletedInterview(null);
		}

	}

	public void failedDeletedInterview(Throwable ex) {
		Window.alert("Could not delete the story.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedUpdateInterview(Object result) {
		if (result == null) {
			failedUpdateInterview(null);
			return;
		}
		Story updatedStory = (Story) result;
		Shelter shelter = interviewForm.story.getShelter();
		shelter.getStories().remove(interviewForm.story);
		shelter.addStory(updatedStory);
		interviewForm.setStory(updatedStory);
		Window.alert("The story was updated");

	}

	public void failedUpdateInterview(Throwable ex) {
		Window.alert("Could not update the story.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedAddInterview(Object result) {
		if (result == null) {
			failedAddInterview(null);
			return;
		}
		
		Story addedStory = (Story) result;
		Shelter shelter = interviewForm.story.getShelter();
		shelter.addStory(addedStory);
		Window.alert("The story was added");
		interviewForm.setStory(new Story());
	}
	
	public void completedAddInterviewCheckFirst(Object result) {
		if (result == null) {
			failedAddInterview(null);
			return;
		}
		
		ArrayList stories = (ArrayList) result;
		if(stories.size() == 1) {
			completedAddInterview(stories.get(0));
		} else {
			String warning = getDuplicateWarningMessage(stories);
			if(Window.confirm(warning)) {
				if(Window.confirm("Are you sure?\n\n(Stories that appear to be the same may indicate \nsomeone is trying to take advantage of the program)")){
					ServerFacade.addInterview(interviewForm.story);
				} else {
					Window.alert("The interview has not been added");
				}
			} else {
				Window.alert("The interview has not been added.");
			}
		}
		
		
	}

	private String getDuplicateWarningMessage(ArrayList stories) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("WARNING: Other stories for this shelter appear to be very similar.\n\n");
		buffer.append("Please review the following list of potential duplicates before proceeding.\n\n");
		for(int x = 0; x < stories.size() - 1; x++){
			Story story = (Story) stories.get(x);
			buffer.append("------------------------------------------------------------\n");
			buffer.append(story.getFirstName());
			buffer.append(" ");
			buffer.append(story.getLastInitial());
			buffer.append(", ");
			buffer.append(story.getAssignedId());
			buffer.append("\n");
			buffer.append(story.getStory());
			buffer.append("\n\n");
		}
		buffer.append("------------------------------------------------------------\n\n");
		buffer.append("If any of these stories appear to be duplicates, please click CANCEL to stop adding this story.\n\n");
		buffer.append("Only click OK if none of these stories appear to match the one you are trying to add.\n\n");
		return buffer.toString();
	}

	public void failedAddInterview(Throwable ex) {
		Window.alert("Could not add the story.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedAddShelter(Object result) {
		if (result == null) {
			failedAddShelter(null);
			return;
		}
		Shelter addedShelter = (Shelter) result;
		User.getInstance().getCurrentCity().getShelters().add(addedShelter);
		Window.alert("The shelter was added");
		shelterForm.setShelter(new Shelter());
	}

	public void completedUpdateShelter(Object result) {
		if (result == null) {
			failedUpdateShelter(null);
			return;
		}
		Shelter updatedShelter = (Shelter) result;
		User.getInstance().getCurrentCity().getShelters().remove(shelterForm.shelter);
		User.getInstance().getCurrentCity().getShelters().add(updatedShelter);
		shelterForm.setShelter(updatedShelter);
		Window.alert("The shelter was updated");
	}

	public void failedUpdateShelter(Throwable ex) {
		Window.alert("Could not update the shelter.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}

	}

	public void completedDeleteShelter(Object result) {
		boolean isDeleted = ((Boolean) result).booleanValue();

		if (isDeleted) {
			Window.alert("The shelter has been deleted.");
			User.getInstance().getCurrentCity().getShelters().remove(shelterForm.shelter);
			shelterForm.setShelter(new Shelter());
		} else {
			failedDeletedShelter(null);
		}

	}

	public void failedDeletedShelter(Throwable ex) {
		Window.alert("Could not delete the shelter.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void failedAddShelter(Throwable ex) {
		Window.alert("Could not add the shelter.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedLoadStories(int shelterId, Object result) {
		if (result == null) {
			failedLoadStories(null);
			return;
		}
		ArrayList shelters = User.getInstance().getCurrentCity().getShelters();
		Shelter shelter = null;
		for (Iterator sheltersIter = shelters.iterator(); sheltersIter.hasNext();) {
			shelter = (Shelter) sheltersIter.next();
			if (shelter.getId() == shelterId) {
				break;
			}
		}
		ArrayList stories = (ArrayList) result;
		for (Iterator storiesIter = stories.iterator(); storiesIter.hasNext();) {
			Story story = (Story) storiesIter.next();
			story.setShelter(shelter);
		}
		editInterviewPanel.refresh(stories);
	}

	public void failedLoadStories(Throwable ex) {
		Window.alert("Could not load the stories.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedDeleteGift(Object result, int giftIndex) {
		boolean isDeleted = ((Boolean) result).booleanValue();
		if (!isDeleted) {
			failedDeleteGift(null);
			return;
		}

	}

	public void failedDeleteGift(Throwable ex) {
		Window.alert("Could not delete the gift.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedCreateNewVolunteer(Object result) {
		if (result == null) {
			failedCreateNewVolunteer(null);
			return;
		}
		boolean value = ((Boolean) result).booleanValue();
		if (value) {
			Window.alert("The volunteer was successfully granted!");
			volunteerPanel.clear();
		} else {
			failedCreateNewVolunteer(null);
		}
	}

	public void failedCreateNewVolunteer(Throwable ex) {
		Window.alert("Could not create the volunteer.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedUpdateVolunteer(Object result) {
		if (result == null) {
			failedUpdateVolunteer(null);
			return;
		}
		boolean value = ((Boolean) result).booleanValue();
		if (value) {
			Window.alert("The volunteer was successfully granted!");
			volunteerPanel.clear();
		} else {
			failedUpdateVolunteer(null);
		}

	}

	public void failedUpdateVolunteer(Throwable ex) {
		Window.alert("Could not update the volunteer.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedUpdatePassword(Object result) {
		if (result == null) {
			failedUpdateVolunteer(null);
			return;
		}
		boolean value = ((Boolean) result).booleanValue();
		if (value) {
			Window.alert("Your password was successfully modified.");
		} else {
			failedUpdateVolunteer(null);
		}
	}

	public void failedUpdatePassword(Throwable ex) {
		Window.alert("Could not update the password.  Please try again later.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void completedGetThankYous(Object result) {
		ArrayList thankyous = (ArrayList) result;
		if(thankyous == null || thankyous.isEmpty()) {
			failedGetThankYous(null);
			return;
		}
		editThankYouPanel.refresh((ArrayList) result);
	}

	public void failedGetThankYous(Throwable ex) {
		Window.alert("No thank you notes found.");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

	public void clearThankYouForm() {
		thankyouForm.setThankYou(new ThankYou());
	}

	public void completedDeleteThankYou(Object result) {
		boolean isDeleted = ((Boolean) result).booleanValue();

		if (isDeleted) {
			Window.alert("The note has been deleted.");
			thankyouForm.setThankYou(new ThankYou());
			showUpdateExistingThankYous();
		} else {
			failedDeletedInterview(null);
		}
	}
	
	public void failedDeleteThankYou(Throwable ex){
		Window.alert("Could not delete the note");
		if (ex != null) {
			Window.alert(ex.getMessage());
		}
	}

}
